package com.md.util;

import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Map;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.md.exception.SystemException;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class JsonSerializer {

	private ObjectMapper mapper = null;

	private static final JsonSerializer DEFAULT = new JsonSerializer();

	public static JsonSerializer getDefault() {
		return DEFAULT;
	}

	public JsonSerializer() {
		mapper = new ObjectMapper();
		mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
	}

	/**
	 * 设置是否缩进。
	 * 
	 * @param indentOutput
	 *            是否缩进。
	 */
	public void setIndentOutput(boolean indentOutput) {
		mapper.configure(SerializationFeature.INDENT_OUTPUT, indentOutput);
	}

	/**
	 * 添加自定义序列化器。
	 * 
	 * @param serializers
	 *            序列化器映射。key为java类，value为key指定的java类对应的序列化器。
	 */
	public void addSerializer(Map<Class<?>, Object> serializers) {
		if (serializers == null || serializers.isEmpty()) {
			return;
		}

		SimpleModule module = new SimpleModule();
		for (Map.Entry<Class<?>, Object> entry : serializers.entrySet()) {
			module.addSerializer(entry.getKey(), (com.fasterxml.jackson.databind.JsonSerializer) entry.getValue());
		}
		this.mapper.registerModule(module);
	}

	/**
	 * 
	 * 序列化为JSON字符串。
	 * 
	 * @return JSON字符串。
	 */
	public String serialize(Object o) {
		try {
			return mapper.writeValueAsString(o);
		} catch (Exception e) {
			throw new SystemException(e);
		}
	}

	/**
	 * 反序列化为java对象。
	 *
	 * @param json
	 *            JSON字符串。
	 * @param target
	 *            目标类型。
	 *
	 * @return 目标类型实例。如果传入的json字符串为空，则返回空。
	 */
	public <T> T deserialize(String jsonString, Class<T> targetClass) {
		try {
			if (DataUtils.isBlank(jsonString)) {
				return null;
			}

			return mapper.readValue(jsonString, targetClass);
		} catch (Exception e) {
			throw new SystemException(e);
		}
	}

	/**
	 * 反序列化为泛型集合。
	 *
	 * @param json
	 *            JSON字符串。
	 * @param collectionType
	 *            集合类型。
	 * @param elementType
	 *            集合泛型。
	 *
	 * @return 泛型集合。如果传入的json字符串为空，则返回空。
	 */
	public <T> Collection<T> deserialize(String jsonString, Class<?> collectionType, Class<T> elementType) {
		try {
			if (DataUtils.isBlank(jsonString)) {
				return null;
			}

			JavaType javaType = mapper.getTypeFactory().constructParametricType(collectionType, elementType);
			return mapper.readValue(jsonString, javaType);
		} catch (Throwable e) {
			throw new SystemException(e);
		}
	}

	/**
	 *
	 * @param jsonString
	 *            JSON字符串。
	 * @param keyClass
	 *            Map的Key的数据类型。
	 * @param valueClass
	 *            Map的Value的数据类型。
	 *
	 * @return Map结构。如果传入的json字符串为空，则返回空。
	 */
	public <K, V> Map<K, V> deserialize(String jsonString, Class<?> mapClass, Class<K> keyClass, Class<V> valueClass) {
		try {
			if (DataUtils.isBlank(jsonString)) {
				return null;
			}

			JavaType javaType = mapper.getTypeFactory().constructMapLikeType(mapClass, keyClass, valueClass);
			return mapper.readValue(jsonString, javaType);
		} catch (Throwable e) {
			throw new SystemException(e);
		}
	}

	// /**
	// * 创建JSON解析器。<br />
	// * 建议尽量不调用此方法。因为会和Jackson产生耦合。
	// *
	// * @param jsonString
	// * json字符串。
	// * @return JSON解析器。
	// */
	// public JsonParser createParser(String jsonString) {
	// try {
	// return mapper.getFactory().createParser(jsonString);
	// } catch (Throwable e) {
	// throw new SystemException(e);
	// }
	// }

	public ObjectMapper getMapper() {
		return this.mapper;
	}

	// /** jackson全局单例对象。 */
	// private static ObjectMapper mapper = new ObjectMapper();
	//
	// static {
	// mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
	// false);
	// mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
	// }
	//
	// public static void registerModule(Module module) {
	// mapper.registerModule(module);
	// }
	//
	// /**
	// * 带缩进的输出。
	// *
	// * @param o
	// * 目标对象。
	// * @return 序列化结果。
	// */
	// public static String serializeWithIndent(Object o) {
	// try {
	// ObjectMapper mapper = new ObjectMapper();
	// mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
	// return mapper.writeValueAsString(o);
	// } catch (Throwable e) {
	// throw new SystemException(e);
	// }
	// }
	//
	// /**
	// * 序列化为JSON字符串。
	// *
	// * @return JSON字符串。
	// */
	// public static String serialize(Object o) {
	// try {
	// return mapper.writeValueAsString(o);
	// } catch (Exception e) {
	// throw new SystemException(e);
	// }
	// }
	//
	// /**
	// * 反序列化为java对象。
	// *
	// * @param json
	// * JSON字符串。
	// * @param target
	// * 目标类型。
	// *
	// * @return 目标类型实例。如果传入的json字符串为空，则返回空。
	// */
	// public static <T> T deserialize(String jsonString, Class<T> targetClass)
	// {
	// try {
	// if (DataUtils.isBlank(jsonString)) {
	// return null;
	// }
	//
	// return mapper.readValue(jsonString, targetClass);
	// } catch (Exception e) {
	// throw new SystemException(e);
	// }
	// }
	//
	// /**
	// * 反序列化为泛型集合。
	// *
	// * @param json
	// * JSON字符串。
	// * @param collectionType
	// * 集合类型。
	// * @param elementType
	// * 集合泛型。
	// *
	// * @return 泛型集合。如果传入的json字符串为空，则返回空。
	// */
	// public static <T> Collection<T> deserialize(String jsonString, Class<?>
	// collectionType, Class<T> elementType) {
	// try {
	// if (DataUtils.isBlank(jsonString)) {
	// return null;
	// }
	//
	// JavaType javaType =
	// mapper.getTypeFactory().constructParametricType(collectionType,
	// elementType);
	// return mapper.readValue(jsonString, javaType);
	// } catch (Throwable e) {
	// throw new SystemException(e);
	// }
	// }
	//
	// /**
	// *
	// * @param jsonString
	// * JSON字符串。
	// * @param keyClass
	// * Map的Key的数据类型。
	// * @param valueClass
	// * Map的Value的数据类型。
	// *
	// * @return Map结构。如果传入的json字符串为空，则返回空。
	// */
	// public static <K, V> Map<K, V> deserialize(String jsonString, Class<?>
	// mapClass, Class<K> keyClass,
	// Class<V> valueClass) {
	// try {
	// if (DataUtils.isBlank(jsonString)) {
	// return null;
	// }
	//
	// JavaType javaType =
	// mapper.getTypeFactory().constructMapLikeType(mapClass, keyClass,
	// valueClass);
	// return mapper.readValue(jsonString, javaType);
	// } catch (Throwable e) {
	// throw new SystemException(e);
	// }
	// }
	//
	// /**
	// * 创建JSON解析器。<br />
	// * 建议尽量不调用此方法。因为会和Jackson产生耦合。
	// *
	// * @param jsonString
	// * json字符串。
	// * @return JSON解析器。
	// */
	// @Deprecated
	// public static JsonParser createParser(String jsonString) {
	// try {
	// return mapper.getFactory().createParser(jsonString);
	// } catch (Throwable e) {
	// throw new SystemException(e);
	// }
	// }

	/**
	 * 反序列化为实体对象。
	 * 
	 * @param jsonString
	 *            JSON字符串。
	 * @param entitySymbol
	 *            实体符号。
	 * @param session
	 *            数据库会话。
	 * 
	 * @return 实体的持久化对象。如果传入的json字符串为空，则返回空。
	 */
	// public static Object deserialize(String jsonString, String entitySymbol,
	// Session session) {
	// try {
	// if (DataUtils.isBlank(jsonString)) {
	// return null;
	// }
	//
	// return new
	// EntityDeserializer(session).deserialize(mapper.getFactory().createParser(jsonString),
	// entitySymbol);
	// } catch (Throwable e) {
	// throw new SystemException(e);
	// }
	// }

}
